﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using OntologyUtility;
using System.Drawing;

namespace OntologyFormDesigner
{
    class UIUtil
    {
        public enum WidgetType {
            OrType,
            AlternativeType, 
            Default
        }

        public static DockStyle DockStyleByString(String dockStyle)
        {
            switch (dockStyle)
            {
                case "None":
                    return DockStyle.None;
                case "Fill":
                    return DockStyle.Fill;
                case "Bottom":
                    return DockStyle.Bottom;
                case "Left":
                    return DockStyle.Left;
                case "Right":
                    return DockStyle.Right;
                case "Top":
                    return DockStyle.Top;
            }

            return DockStyle.None;
        }

         public static AnchorStyles AnchorStyleByString(String anchorStyle)
        {
            String[] anchorStyles = anchorStyle.Split(',');
            AnchorStyles anchorReturn = AnchorStyles.None;
            bool first = true;
            foreach (String anchor in anchorStyles) 
            {
                switch (anchor.Trim())
                {
                    case "None":
                        if (first) { anchorReturn = AnchorStyles.None; first = false; } else anchorReturn |= AnchorStyles.None; 
                        break;
                    case "Bottom":
                        if (first) { anchorReturn = AnchorStyles.Bottom; first = false; } else anchorReturn |= AnchorStyles.Bottom; 
                        break;
                    case "Left":
                        if (first) { anchorReturn = AnchorStyles.Left; first = false; } else anchorReturn |= AnchorStyles.Left; 
                        break;
                    case "Right":
                        if (first) { anchorReturn = AnchorStyles.Right; first = false; } else anchorReturn |= AnchorStyles.Right; 
                        break;
                    case "Top":
                        if (first) { anchorReturn = AnchorStyles.Top; first = false; } else anchorReturn |= AnchorStyles.Top; 
                        break;
                }
            }

            return AnchorStyles.None;
        }

        public static WidgetType GetWidgetTypeFromType(Type type)
        {
            WidgetType widget = WidgetType.Default;

            if (typeof(OntologyUtility.Interfaces.IOrWidget).IsAssignableFrom(type))
            {
                widget = WidgetType.OrType;
            }
            else if (typeof(OntologyUtility.Interfaces.IAlternativeWidget).IsAssignableFrom(type))
            {
                widget = WidgetType.AlternativeType;
            }

            return widget;
        }
        public static TreeView createTreeView(Node node, Type type)
        {
            
            TreeView treeView = new TreeView();
            treeView.Dock = DockStyle.Fill;
            TreeNode root = new TreeNode(node.Name);
            root.Name = node.Name;
            root.Text = node.Name + ((node.Type == null) ? "" : " ( " + node.Type + " ) ");
            root.Tag = node;

            recursiveTree(node, ref root, GetWidgetTypeFromType(type));

            treeView.Nodes.Add(root);
            treeView.ExpandAll();

            return treeView;
        }

        public static TreeView createTreeView(Node node)
        {

            TreeView treeView = new TreeView();
            treeView.Dock = DockStyle.Fill;
            TreeNode root = new TreeNode(node.Name);
            root.Name = node.Name;
            root.Text = node.Name + ((node.Type == null) ? "" : " ( " + node.Type + " ) ");
            root.Tag = node;

            recursiveTree(node, ref root);

            treeView.Nodes.Add(root);
            treeView.ExpandAll();

            return treeView;
        }

        private static String GetChildren(Node node)
        {
            String sChildren = node.Name + " [";
            int index = 1;
            int max = node.Childs.Count;
            foreach (Node child in node.Childs)
                sChildren += (max == index++) ? (child.Name + "]") : (child.Name + ", ");

            return sChildren;
        }
        public static TreeView createFlatTreeView(Node node, Type type)
        {
            TreeView treeView = new TreeView();
            treeView.Dock = DockStyle.Fill;
            TreeNode root = new TreeNode(node.Name);
            root.Name = node.Name;
            root.Text = GetChildren(node); 
            root.Tag = node;

            try
            {
                switch (GetWidgetTypeFromType(type))
                {
                    case WidgetType.AlternativeType:
                        if (node.Type.Equals("AlternativeType"))
                        {
                            treeView.Nodes.Add(root);
                        }
                        break;
                    case WidgetType.OrType:
                        if (node.Type.Equals("OrType"))
                        {

                            treeView.Nodes.Add(root);
                        }
                        break;
                    default:

                        break;
                }
            }
            catch (Exception)
            {
                //TODO:
            }

            recursiveFlatTree(node, ref treeView, GetWidgetTypeFromType(type));

            treeView.ExpandAll();

            return treeView;
        }

        
        private static void recursiveFlatTree(Node node, ref TreeView treeView, WidgetType widgetType)
        {

            foreach (Node node2 in node.Childs)
            {
                TreeNode tNode = new TreeNode(node2.Name);
                tNode.Name = node2.Name;
                tNode.Text = GetChildren(node2); 
                tNode.Tag = node2;
                recursiveFlatTree(node2, ref treeView, widgetType);
                try
                {
                    switch (widgetType)
                    {
                        case WidgetType.AlternativeType:
                            if (node2.Type.Equals("AlternativeType"))
                            {
                                treeView.Nodes.Add(tNode);
                            }
                            break;
                        case WidgetType.OrType:
                            if (node2.Type.Equals("OrType"))
                            {

                                treeView.Nodes.Add(tNode);
                            }
                            break;
                        default:

                            break;
                    }
                }
                catch (Exception)
                {
                    //TODO:
                }
            }
        }

        private static void recursiveTree(Node node, ref TreeNode root, WidgetType widgetType)
        {
           
            foreach (Node node2 in node.Childs)
            {
                TreeNode tNode = new TreeNode(node2.Name);
                tNode.Name = node2.Name;
                tNode.Text = node2.Name + ((node2.Type == null) ? "" : " ( " + node2.Type + " ) ");
                tNode.Tag = node2;
                recursiveTree(node2, ref tNode, widgetType);
                if (node.Type.Equals("OptionalType"))
                {
                    root.Nodes.Add(tNode);
                }
                else
                {
                    switch (widgetType)
                    {
                        case WidgetType.AlternativeType:
                            if (node.Type.Equals("AlternativeType"))
                            {
                                
                                root.Nodes.Add(tNode);
                            }
                            break;
                        case WidgetType.OrType:
                            if (node.Type.Equals("OrType"))
                            {
                                
                                root.Nodes.Add(tNode);
                            }
                            break;
                        default:

                            break;
                    }
                }
            }
        }

        private static void recursiveTree(Node node, ref TreeNode root)
        {

            foreach (Node node2 in node.Childs)
            {
                TreeNode tNode = new TreeNode(node2.Name);
                tNode.Name = node2.Name;
                tNode.Text = node2.Name + ((node2.Type == null) ? "" : " ( " + node2.Type + " ) ");
                tNode.Tag = node2;
                recursiveTree(node2, ref tNode);
                root.Nodes.Add(tNode);

            }
        }

        public static Label createLabel(String s, Boolean border, float fontDim, DockStyle dock, FontStyle style) 
        {
            Label label = new Label();
            label.Text = s;
            label.Dock = dock;
            label.Font = new System.Drawing.Font("Microsoft Sans Serif", fontDim, style, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            label.ForeColor = UIUtil.COLOR_BLUE;
            //label.BackColor = UIUtil.COLOR_YELLOW;
            label.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
            label.BorderStyle = border ? System.Windows.Forms.BorderStyle.Fixed3D : System.Windows.Forms.BorderStyle.None;
            return label;
        }

        public static Label createLabel(String s, Boolean border, float fontDim, AnchorStyles anchor, FontStyle style)
        {
            Label label = new Label();
            label.Text = s;
            label.Anchor = anchor;
            label.Font = new System.Drawing.Font("Microsoft Sans Serif", fontDim, style, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            label.ForeColor = UIUtil.COLOR_BLUE;
            label.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
            label.BorderStyle = border ? System.Windows.Forms.BorderStyle.FixedSingle : System.Windows.Forms.BorderStyle.None;
            return label;
        }

        public static Button createButton(String toolTip, Object tag, Image image, EventHandler _event)
        {
            Button btn = new Button();
            btn.Image = image;
            btn.Dock = DockStyle.Fill;
            btn.FlatAppearance.BorderSize = 0;
            btn.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
            btn.Click += _event;
            btn.Tag = tag;
            ToolTip tip = new ToolTip();
            tip.SetToolTip(btn, toolTip);

            return btn;
        }

        public static TabPage createTabPage(String text, ref TabControl control, ref ListBox listbox) 
        {
            TabPage page = new TabPage()
            {
                Padding = new System.Windows.Forms.Padding(0),
                Text = text
            };
            listbox = new ListBox();
            listbox.Dock = DockStyle.Fill;
            page.Controls.Add(listbox);

            control.Controls.Add(page);
            return page;
        }

        public static Color GetColorByRGB(int r, int g, int b)
        {
            try
            {
                return System.Drawing.Color.FromArgb(r, g, b);
            }
            catch (Exception)
            {
                throw;
            }
        }

        public static Color GetColorByRGB(String rgb)
        {
            try
            {
                String[] rgbs = rgb.Split(',');
                return System.Drawing.Color.FromArgb(
                    Int32.Parse(rgbs[0]),
                    Int32.Parse(rgbs[1]),
                    Int32.Parse(rgbs[2]));
            }
            catch (Exception)
            {
                
                throw;
            }
        }

        public static Color COLOR_BLUE = System.Drawing.Color.FromArgb(((int)(((byte)(41)))), ((int)(((byte)(57)))), ((int)(((byte)(85)))));
        public static Color COLOR_YELLOW = System.Drawing.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(255)))), ((int)(((byte)(192)))));
        public static Color COLOR_GRAY = System.Drawing.Color.FromArgb(((int)(((byte)(240)))), ((int)(((byte)(240)))), ((int)(((byte)(240)))));
        public static Color COLOR_WHITE = System.Drawing.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(255)))), ((int)(((byte)(255)))));
    }
}
